package org.jim.core.packets;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

public class Command {
  // 预定义的命令实例
  public static final Command COMMAND_UNKNOW = new Command("COMMAND_UNKNOW", 0);
  public static final Command COMMAND_HANDSHAKE_REQ = new Command("COMMAND_HANDSHAKE_REQ", 1);
  public static final Command COMMAND_HANDSHAKE_RESP = new Command("COMMAND_HANDSHAKE_RESP", 2);
  public static final Command COMMAND_AUTH_REQ = new Command("COMMAND_AUTH_REQ", 3);
  public static final Command COMMAND_AUTH_RESP = new Command("COMMAND_AUTH_RESP", 4);
  public static final Command COMMAND_LOGIN_REQ = new Command("COMMAND_LOGIN_REQ", 5);
  public static final Command COMMAND_LOGIN_RESP = new Command("COMMAND_LOGIN_RESP", 6);
  public static final Command COMMAND_JOIN_GROUP_REQ = new Command("COMMAND_JOIN_GROUP_REQ", 7);
  public static final Command COMMAND_JOIN_GROUP_RESP = new Command("COMMAND_JOIN_GROUP_RESP", 8);
  public static final Command COMMAND_JOIN_GROUP_NOTIFY_RESP = new Command("COMMAND_JOIN_GROUP_NOTIFY_RESP", 9);
  public static final Command COMMAND_EXIT_GROUP_NOTIFY_RESP = new Command("COMMAND_EXIT_GROUP_NOTIFY_RESP", 10);
  public static final Command COMMAND_CHAT_REQ = new Command("COMMAND_CHAT_REQ", 11);
  public static final Command COMMAND_CHAT_RESP = new Command("COMMAND_CHAT_RESP", 12);
  public static final Command COMMAND_HEARTBEAT_REQ = new Command("COMMAND_HEARTBEAT_REQ", 13);
  public static final Command COMMAND_CLOSE_REQ = new Command("COMMAND_CLOSE_REQ", 14);
  public static final Command COMMAND_CANCEL_MSG_REQ = new Command("COMMAND_CANCEL_MSG_REQ", 15);
  public static final Command COMMAND_CANCEL_MSG_RESP = new Command("COMMAND_CANCEL_MSG_RESP", 16);
  public static final Command COMMAND_GET_USER_REQ = new Command("COMMAND_GET_USER_REQ", 17);
  public static final Command COMMAND_GET_USER_RESP = new Command("COMMAND_GET_USER_RESP", 18);
  public static final Command COMMAND_GET_MESSAGE_REQ = new Command("COMMAND_GET_MESSAGE_REQ", 19);
  public static final Command COMMAND_GET_MESSAGE_RESP = new Command("COMMAND_GET_MESSAGE_RESP", 20);

  public static final Command COMMAND_OTHER_RESP = new Command("COMMAND_OTHER_RESP", 999);

  // 存储所有命令实例，支持动态添加
  private static final List<Command> ALL_VALUES = new CopyOnWriteArrayList<>();
  // 缓存名称到实例的映射，提高查询效率
  private static final Map<String, Command> NAME_MAP = new ConcurrentHashMap<>();
  // 缓存数值到实例的映射，提高查询效率
  private static final Map<Integer, Command> VALUE_MAP = new ConcurrentHashMap<>();

  // 静态初始化块，初始化预定义的命令
  static {
    // 添加预定义的命令到集合中
    ALL_VALUES.addAll(Arrays.asList(
            COMMAND_UNKNOW,
            COMMAND_HANDSHAKE_REQ,
            COMMAND_HANDSHAKE_RESP,
            COMMAND_AUTH_REQ,
            COMMAND_AUTH_RESP,
            COMMAND_LOGIN_REQ,
            COMMAND_LOGIN_RESP,
            COMMAND_JOIN_GROUP_REQ,
            COMMAND_JOIN_GROUP_RESP,
            COMMAND_JOIN_GROUP_NOTIFY_RESP,
            COMMAND_EXIT_GROUP_NOTIFY_RESP,
            COMMAND_CHAT_REQ,
            COMMAND_CHAT_RESP,
            COMMAND_HEARTBEAT_REQ,
            COMMAND_CLOSE_REQ,
            COMMAND_CANCEL_MSG_REQ,
            COMMAND_CANCEL_MSG_RESP,
            COMMAND_GET_USER_REQ,
            COMMAND_GET_USER_RESP,
            COMMAND_GET_MESSAGE_REQ,
            COMMAND_GET_MESSAGE_RESP,
            COMMAND_OTHER_RESP
    ));

    // 初始化映射缓存
    for (Command command : ALL_VALUES) {
      NAME_MAP.put(command.name, command);
      VALUE_MAP.put(command.value, command);
    }
  }

  private final String name;
  private final int value;

  private Command(String name, int value) {
    this.name = name;
    this.value = value;
  }

  /**
   * 获取命令的名称
   */
  public String name() {
    return name;
  }

  public final int getNumber() {
    return value;
  }

  /**
   * 通过数值获取对应的Command实例
   */
  public static Command valueOf(int value) {
    Command command = VALUE_MAP.get(value);
    if (command == null) {
      return COMMAND_OTHER_RESP;
    }
    return command;
  }

  /**
   * 通过名称获取对应的Command实例
   */
  public static Command valueOf(String name) {
    Command command = NAME_MAP.get(name);
    if (command == null) {
      throw new IllegalArgumentException("No command with name: " + name);
    }
    return command;
  }

  public static Command forNumber(int value) {
    return valueOf(value);
  }

  /**
   * 获取所有命令类型的数组
   */
  public static Command[] values() {
    return ALL_VALUES.toArray(new Command[0]);
  }

  /**
   * 动态添加新的命令
   * @param name 命令名称
   * @param value 命令数值
   * @return 新创建的命令实例
   * @throws IllegalArgumentException 如果名称或数值已存在
   */
  public static Command addAndGet(String name, int value) {
    // 检查名称和数值是否已存在
    if (NAME_MAP.containsKey(name)) {
      return NAME_MAP.get(name);
    }
    if (VALUE_MAP.containsKey(value)) {
      throw new IllegalArgumentException("Command value already exists: " + value);
    }

    // 创建新的命令实例
    Command newCommand = new Command(name, value);

    // 添加到集合和缓存中
    ALL_VALUES.add(newCommand);
    NAME_MAP.put(name, newCommand);
    VALUE_MAP.put(value, newCommand);

    return newCommand;
  }

  @Override
  public String toString() {
    return name;
  }
}
